﻿using AutoMapper;
using MD5Hash;
using Medical.Api.Read.Dto.RBAC;
using Medical.Domain.RBAC;
using Medical.ErrorCode;
using Medical.Interstructrue.Base;

namespace Medical.Api.Read.Service.RBAC
{
    public class RBACService : IRBACService
    {
        private readonly IBaseRepository<UserModel> _userRepository;
        private readonly IBaseRepository<RoleModel> _roleRepository;
        private readonly IBaseRepository<UserRoleModel> _userRoleRepository;
        private readonly IBaseRepository<RolePermissionModel> _rolePermissionRepository;
        private readonly IBaseRepository<PermissionModel> _permissionRepository;
        private readonly IMapper mapper;
        private readonly ILogger<RBACService> _logger;

        public RBACService(IBaseRepository<UserModel> userRepository, IBaseRepository<RoleModel> roleRepository, IBaseRepository<UserRoleModel> userRoleRepository, IBaseRepository<RolePermissionModel> rolePermissionRepository, IBaseRepository<PermissionModel> permissionRepository, IMapper mapper, ILogger<RBACService> logger)
        {
            _userRepository = userRepository;
            _roleRepository = roleRepository;
            _userRoleRepository = userRoleRepository;
            _rolePermissionRepository = rolePermissionRepository;
            _permissionRepository = permissionRepository;
            this.mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="UserName">用户名</param>
        /// <param name="Password">密码</param>
        /// <returns></returns>
        public ApiResult<LoginDto> Login(string UserName, string Password)
        {
            ApiResult<LoginDto> res = new ApiResult<LoginDto>();
            try
            {
                // 1. 验证用户是否存在
                var user = _userRepository.GetAll().FirstOrDefault(x => x.UserName == UserName);
                if (user == null)
                {
                    res.Code = ApiEnums.Fail;
                    res.Msg = "用户不存在";
                    _logger.LogWarning($"登录失败：用户 {UserName} 不存在");
                    return res;
                }

                // 2. 验证密码
                var pwd = Password.GetMD5();
                if (user.Password != pwd)
                {
                    res.Code = ApiEnums.Fail;
                    res.Msg = "密码错误";
                    _logger.LogWarning($"登录失败：用户 {UserName} 密码错误");
                    return res;
                }

                // 3. 获取用户所有角色
                var userRoles = _userRoleRepository.GetAll().Where(x => x.UserId == user.Id).ToList();
                if (!userRoles.Any())
                {
                    res.Code = ApiEnums.Fail;
                    res.Msg = "用户未分配角色";
                    _logger.LogWarning($"登录失败：用户 {UserName} 未分配角色");
                    return res;
                }

                // 4. 获取所有角色信息
                var roleIds = userRoles.Select(x => x.RoleId).ToList();
                var roles = _roleRepository.GetAll().Where(x => roleIds.Contains(x.Id)).ToList();

                // 5. 组装角色及权限信息
                var roleDtos = new List<RoleDto>();
                foreach (var role in roles)
                {
                    // 获取该角色的所有权限
                    var rolePermissions = _rolePermissionRepository.GetAll().Where(x => x.RoleId == role.Id).ToList();
                    var permissionIds = rolePermissions.Select(x => x.PermissionId).ToList();
                    var permissions = _permissionRepository.GetAll().Where(x => permissionIds.Contains(x.Id)).ToList();

                    var permissionDtos = permissions.Select(p => new PermissionDto
                    {
                        PermissionId = p.Id,
                        PermissionName = p.PermissionName,
                        PermissionUrl = p.PermissionURL,
                        ParentId = p.ParentId // 新增：上级Id
                    }).ToList();

                    roleDtos.Add(new RoleDto
                    {
                        RoleId = role.Id,
                        RoleName = role.RoleName,
                        Permissions = permissionDtos
                    });
                }

                // 6. 构建登录返回信息
                var loginDto = new LoginDto
                {
                    UserName = user.UserName,
                    Password = "", // 不返回密码

                    UserId = user.Id,
                    Roles = roleDtos,
                    Token = "" // 暂时为空，后续可生成Token
                };

                res.Data = loginDto;
                res.Code = ApiEnums.Success;
                res.Msg = "登录成功";
                _logger.LogInformation($"用户 {UserName} 登录成功，角色数: {roleDtos.Count}");
            }
            catch (Exception ex)
            {
                res.Code = ApiEnums.Fail;
                res.Msg = $"登录过程中发生异常: {ex.Message}";
                _logger.LogError(ex, $"用户 {UserName} 登录过程中发生异常");
            }
            return res;
        }
    }
}
